package com.ml.mall.service.category.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ml.mall.bean.base.ApiRestResult;
import com.ml.mall.bean.page.Page;
import com.ml.mall.bean.req.category.*;
import com.ml.mall.bean.res.category.*;
import com.ml.mall.consts.CommonConsts;
import com.ml.mall.entity.category.SysACategory;
import com.ml.mall.entity.sys.SysUser;
import com.ml.mall.enums.CommonEnum;
import com.ml.mall.enums.SysSeqNameEnum;
import com.ml.mall.exception.BizException;
import com.ml.mall.mapper.category.SysACategoryMapper;
import com.ml.mall.security.JwtUtil;
import com.ml.mall.service.category.SysACategoryService;
import com.ml.mall.service.common.CommonSeqService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
public class SysACategoryServiceImpl extends ServiceImpl<SysACategoryMapper, SysACategory> implements SysACategoryService {

    @Autowired
    private CommonSeqService commonSeqService;
    @Autowired
    private SysACategoryMapper sysACategoryMapper;


    @Override
    @Transactional
    public ApiRestResult createCategory(CategoryNewDto dto) {
        SysACategory dbCategory = sysACategoryMapper.selectByCategoryName(dto.getCategoryName());
        if (dbCategory != null) {
            throw new BizException(CommonEnum.ALREADY_EXISTS_CATEGORY);
        }
        SysACategory sysACategory = new SysACategory();
        BeanUtils.copyProperties(dto, sysACategory);
        sysACategory.setParentId("0");
        Long categoryId = commonSeqService.nextSysOrderSeq(SysSeqNameEnum.CATEGORY_ROOT_ID.getCode(),0);
        sysACategory.setCategoryId(categoryId.toString());
        sysACategory.setState(CommonConsts.FIXED_NUM_ZERO);
        sysACategory.setSonsNum(0);
        sysACategory.setTreeName(dto.getCategoryName());
        int isAdd = sysACategoryMapper.insert(sysACategory);

        if (isAdd < 1) {
            throw new BizException(CommonEnum.INSERT_ERROR);
        }

        CategoryAddRes categoryAddRes = new CategoryAddRes();
        categoryAddRes.setCategoryId(categoryId.toString());

        return ApiRestResult.ok(categoryAddRes);
    }

    @Override
    @Transactional
    public ApiRestResult editCategory(CategoryEditDto dto) {
        SysACategory sysACategory = new SysACategory();
        BeanUtils.copyProperties(dto, sysACategory);
        if(dto.getCategoryName() != null){
            SysACategory dbSameNameCategory = sysACategoryMapper.selectByCategoryName(dto.getCategoryName());
            SysACategory dbOriginCategory = sysACategoryMapper.selectById(sysACategory);
            if (dbSameNameCategory != null && !dto.getCategoryName().equals(dbOriginCategory.getCategoryName())) {
                throw new BizException(CommonEnum.ALREADY_EXISTS_CATEGORY);
            }
            //更新目录名的同时更新treeName
            SysACategory parentCategory = sysACategoryMapper.selectByCategoryId(dbOriginCategory.getParentId());
            String treeName = dto.getCategoryName();
            if(parentCategory != null){
                treeName = parentCategory.getTreeName() + "/" + treeName;
            }
            //更新本目录及子目录的treeName
            sysACategoryMapper.updateTreeNameByRoot(dbOriginCategory.getCategoryId(), dbOriginCategory.getTreeName(), treeName);
        }
        int isUpdate = sysACategoryMapper.updateById(sysACategory);
        if (isUpdate < 1) {
            throw new BizException(CommonEnum.UPDATE_ERROR);
        }
        return ApiRestResult.ok();
    }

    @Transactional
    @Override
    public ApiRestResult removeCategory(List<Long> ids) {
        for (Long id:ids) {
            // 判断大目录下面是否有子目录
            SysACategory category = sysACategoryMapper.selectById(id);
            LambdaQueryWrapper<SysACategory> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(SysACategory::getParentId,category.getCategoryId());
            List<SysACategory> categoryList = sysACategoryMapper.selectList(wrapper);
            log.info("要删除目录的子目录为【{}】",categoryList);
            if(categoryList == null || categoryList.size() == 0){
                sysACategoryMapper.deleteById(id);
                // 减少该父目录的孩子数量
                sysACategoryMapper.updateParentCategorySonsNum(CommonConsts.IS_REDUCE,category.getParentId());
            }else {
                throw new BizException(CommonEnum.NOT_ALLOWED_TO_DELETE.getResultCode(),
                        "【"+ category.getCategoryName() +"】"+CommonEnum.NOT_ALLOWED_TO_DELETE.getResultMsg());
            }
        }
        return ApiRestResult.ok();
    }

    @Override
    public CategoryTree queryTreeCategory(CategoryDto dto) {
        List<CategoryTree> categoryList = sysACategoryMapper.selectCategoryTree(dto);
        String rootId = dto.getCategoryId();

        List<CategoryTree> categoryTreeList = categoryList.stream().filter(category ->
                rootId.equals(category.getCategoryId())
        ).peek(category ->{
            List<CategoryTree> children = getChildren(category,categoryList);
            category.setChildren(children);
            category.setSonsNum(children.size());
         }
        ).collect(Collectors.toList());
        log.info("categoryTreeList==={}",categoryTreeList);
        CategoryTree categoryTree = null;
        if(categoryTreeList != null && categoryTreeList.size() > 0){
            categoryTree = categoryTreeList.get(0);
        }
        return categoryTree;
    }

    private List<CategoryTree> getChildren(CategoryTree root, List<CategoryTree> categoryList) {
        List<CategoryTree> children = categoryList.stream().filter(category ->
            category.getParentId().equals(root.getCategoryId())
        ).map(category -> {
            List<CategoryTree> sons =getChildren(category, categoryList);
            category.setChildren(sons);
            category.setSonsNum(sons.size());
            return category;
        }).sorted(Comparator.comparing(CategoryTree::getIndexNo)).collect(Collectors.toList());
        return children;
    }

    @Override
    public Page<CategoryRes> queryPageCategory(CategoryQueryDto dto) {
        Page<CategoryRes> page = new Page<>(dto.getPageIndex(), dto.getPageNum());
        List<CategoryRes> categoryResList = sysACategoryMapper.selectPageCategory(dto);
        Long count = sysACategoryMapper.countCategory(dto);
        page.setRecords(categoryResList);
        page.setTotal(count.intValue());
        return page;
    }

    @Transactional
    @Override
    public ApiRestResult addSubCategory(CategorySubNewDto dto) {
        SysACategory category = sysACategoryMapper.selectByCategoryName(dto.getCategoryName());
        if(category != null){
            throw new BizException(CommonEnum.ALREADY_EXISTS_CATEGORY);
        }
        SysACategory dbSysACategory = sysACategoryMapper.selectByCategoryId(dto.getParentId());
        if(dbSysACategory == null){
            throw new BizException(CommonEnum.NO_EXISTS_CATEGORY);
        }
        //父目录子目录数量加一

        SysACategory sysACategory = new SysACategory();
        BeanUtils.copyProperties(dto,sysACategory);
        sysACategory.setState(CommonConsts.FIXED_NUM_ZERO);
        String subCategory = dto.getParentId()+"C"+commonSeqService.nextSeq(SysSeqNameEnum.CATEGORY_SUB_ID.getCode());
        sysACategory.setCategoryId(subCategory);
        //查询父目录的产业信息
        SysACategory parentCategory = sysACategoryMapper.selectByCategoryId(dto.getParentId());
        sysACategory.setIndustryId(parentCategory.getIndustryId());
        sysACategory.setTreeName(parentCategory.getTreeName() + "/" + dto.getCategoryName()  );
        sysACategory.setSonsNum(0);
        //拆分出根目录
        String[] cs = dto.getParentId().split("C");
        sysACategory.setRootCategoryId(cs[0]);
        int isAdd = sysACategoryMapper.insert(sysACategory);
        sysACategoryMapper.updateParentCategorySonsNum(CommonConsts.IS_ADD,dto.getParentId());
        if(isAdd < 1){
            throw new BizException(CommonEnum.INSERT_ERROR);
        }
        return ApiRestResult.ok();
    }

    @Override
    public List<CategoryBriefRes> queryLevel1Category(CategoryDto dto) {
        List<CategoryBriefRes> categoryBriefResList = sysACategoryMapper.selectSubCategory(dto.getCategoryId());
        return categoryBriefResList;
    }

    @Override
    public ApiRestResult queryAllSubByRootCategoryId(CategoryQueryAllSubDto dto){
        List<SysACategory> sysACategories = sysACategoryMapper.selectAllSub(dto.getCategoryId());
        return ApiRestResult.ok(sysACategories);
    }

    @Override
    public ApiRestResult categorySearch(CategorySearchDto dto) {
        SysUser sysUser =  JwtUtil.getCurrentUser();
        List<CategorySearchRes> list =  sysACategoryMapper.selectCategorySearchList(sysUser.getCompanyId());
        return ApiRestResult.ok(list);
    }
}
